/**
************************************************************
* @file         gizwits_product.c
* @brief        Gizwits control protocol processing, and platform-related       hardware initialization
* @author       Gizwits
* @date         2017-07-19
* @version      V03030000
* @copyright    Gizwits
*
* @note         机智云.只为智能硬件而生
*               Gizwits Smart Cloud  for Smart Products
*               链接|增值ֵ|开放|中立|安全|自有|自由|生态
*               www.gizwits.com
*
***********************************************************/

#include <stdio.h>
#include <string.h>
#include "hal_key.h"
#include "gizwits_product.h"
#include "common.h"
#include "Hal_led.h"
static uint32_t timerMsCount;
uint8_t aRxBuffer;

/** User area the current device state structure*/
dataPoint_t currentDataPoint;
extern keysTypedef_t keys;

extern TIM_HandleTypeDef htim2;
extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart2;

/**@} */
/**@name Gizwits User Interface
* @{
*/

/**
* @brief Event handling interface

* Description:

* 1. Users can customize the changes in WiFi module status

* 2. Users can add data points in the function of event processing logic, such as calling the relevant hardware peripherals operating interface

* @param [in] info: event queue
* @param [in] data: protocol data
* @param [in] len: protocol data length
* @return NULL
* @ref gizwits_protocol.h
*/
int8_t gizwitsEventProcess(eventInfo_t *info, uint8_t *gizdata, uint32_t len)
{
    uint8_t i = 0;
    dataPoint_t *dataPointPtr = (dataPoint_t *)gizdata;
    moduleStatusInfo_t *wifiData = (moduleStatusInfo_t *)gizdata;
    protocolTime_t *ptime = (protocolTime_t *)gizdata;

#if MODULE_TYPE
    gprsInfo_t *gprsInfoData = (gprsInfo_t *)gizdata;
#else
    moduleInfo_t *ptModuleInfo = (moduleInfo_t *)gizdata;
#endif

    if((NULL == info) || (NULL == gizdata))
    {
        return -1;
    }

    for(i=0; i<info->num; i++)
    {
        switch(info->event[i])
        {

					 case EVENT_BoomOpen:
						  if( currentDataPoint.valueMODEL== 0)
                break;
            currentDataPoint.valueBoomOpen = dataPointPtr->valueBoomOpen;
            GIZWITS_LOG("Evt: EVENT_BoomOpen %d \n", currentDataPoint.valueBoomOpen);
            if(0x01 == currentDataPoint.valueBoomOpen)
            {
                HUMON;//user handle
            }
            else
            {
                HUMOFF;//user handle
            }
            break;
        case EVENT_addhumiopen:
							 if( currentDataPoint.valueMODEL== 0)
                break;
            currentDataPoint.valueaddhumiopen = dataPointPtr->valueaddhumiopen;
            GIZWITS_LOG("Evt: EVENT_addhumiopen %d \n", currentDataPoint.valueaddhumiopen);
            if(0x01 == currentDataPoint.valueaddhumiopen)
            {
                LEDON;//user handle
            }
            else
            {
                LEDOFF;//user handle 
            }
            break;
       case EVENT_LED:
				  if( currentDataPoint.valueMODEL== 0)
                break;
            currentDataPoint.valueLED = dataPointPtr->valueLED;
            GIZWITS_LOG("Evt: EVENT_LED %d \n", currentDataPoint.valueLED);
            if(0x01 == currentDataPoint.valueLED)
            {
            LED1ON;//user handle
            }
            else
            {
            LED1OFF;//user handle    
            }
            break;
        case EVENT_MODEL:
            currentDataPoint.valueMODEL = dataPointPtr->valueMODEL;
            GIZWITS_LOG("Evt: EVENT_MODEL %d\n", currentDataPoint.valueMODEL);
            switch(currentDataPoint.valueMODEL)
            {
            case MODEL_VALUE0:
                //user handle
                break;
            case MODEL_VALUE1:
                //user handle
                break;
            default:
                break;
            }
            break;

        case EVENT_SoilSet:
            currentDataPoint.valueSoilSet = dataPointPtr->valueSoilSet;
            GIZWITS_LOG("Evt:EVENT_SoilSet %d\n",currentDataPoint.valueSoilSet);
            //user handle
            break;
        case EVENT_HumiSet:
            currentDataPoint.valueHumiSet = dataPointPtr->valueHumiSet;
            GIZWITS_LOG("Evt:EVENT_HumiSet %d\n",currentDataPoint.valueHumiSet);
            //user handle
            break;
        case EVENT_TempSet:
            currentDataPoint.valueTempSet = dataPointPtr->valueTempSet;
            GIZWITS_LOG("Evt:EVENT_TempSet %d\n",currentDataPoint.valueTempSet);
            //user handle
            break;
						
					 case EVENT_lightset:
            currentDataPoint.valuelightset = dataPointPtr->valuelightset;
            GIZWITS_LOG("Evt:EVENT_lightset %d\n",currentDataPoint.valuelightset);
            //user handle
            break;	
//        case EVENT_TempLimit:
//            currentDataPoint.valueTempSet = dataPointPtr->valueTempSet;
//            GIZWITS_LOG("Evt:EVENT_TempLimit %d\n",currentDataPoint.valueTempSet);
//            //user handle
//            break;
//        case EVENT_HumLimit:
//            currentDataPoint.valueHumiSet = dataPointPtr->valueHumiSet;
//            GIZWITS_LOG("Evt:EVENT_HumLimit %d\n",currentDataPoint.valueHumiSet);
//            //user handle
//            break;
//        case EVENT_CH4Limit:
//            currentDataPoint.valueSoilSet = dataPointPtr->valueSoilSet;
//            GIZWITS_LOG("Evt:EVENT_CH4Limit %d\n",currentDataPoint.valueSoilSet);
//            //user handle
//            break;


        case WIFI_SOFTAP:
            break;
        case WIFI_AIRLINK:
            break;
        case WIFI_STATION:
            break;
        case WIFI_CON_ROUTER:

            break;
        case WIFI_DISCON_ROUTER:

            break;
        case WIFI_CON_M2M:

            break;
        case WIFI_DISCON_M2M:
            break;
        case WIFI_RSSI:
            GIZWITS_LOG("RSSI %d\n", wifiData->rssi);
            break;
        case TRANSPARENT_DATA:
            GIZWITS_LOG("TRANSPARENT_DATA \n");
            //user handle , Fetch data from [data] , size is [len]
            break;
        case WIFI_NTP:
            GIZWITS_LOG("WIFI_NTP : [%d-%d-%d %02d:%02d:%02d][%d] \n",ptime->year,ptime->month,ptime->day,ptime->hour,ptime->minute,ptime->second,ptime->ntp);
            break;
        case MODULE_INFO:
            GIZWITS_LOG("MODULE INFO ...\n");
#if MODULE_TYPE
            GIZWITS_LOG("GPRS MODULE ...\n");
            //Format By gprsInfo_t
#else
            GIZWITS_LOG("WIF MODULE ...\n");
            //Format By moduleInfo_t
            GIZWITS_LOG("moduleType : [%d] \n",ptModuleInfo->moduleType);
#endif
            break;
        default:
            break;
        }
    }

    return 0;
}

/**
* User data acquisition

* Here users need to achieve in addition to data points other than the collection of data collection, can be self-defined acquisition frequency and design data filtering algorithm

* @param none
* @return none
*/
#include "hal_temp_hum.h"
#include "adc.h"
#include "hal_oled.h"
#include "Cds18b20.h"
extern u8 MenuNum;
extern void modeset(uint8_t ui);
void userHandle(void)
{
    /*
         currentDataPoint.valueTempSet = ;
         currentDataPoint.valueHumiSet = ;
         currentDataPoint.valueSoilSet = ;
         currentDataPoint.valueAirTemp = ;
         currentDataPoint.valueAirHum = ;
         currentDataPoint.valueSoilHum = ;


       */
    uint8_t ret = 0;
    static uint32_t thLastTimer = 0;

    if((gizGetTimerCount() - thLastTimer) > 1000 )      //上报间隔读取温度2S
    {

        modeset(currentDataPoint.valueMODEL);
        //采集三种数据
		   	dht11Read((u8*)&currentDataPoint.valueAirTemp,(u8*)&currentDataPoint.valueAirHum);

        currentDataPoint.valueSoilHum =(uint16_t)(Get_Adc_Average(ADC_CHANNEL_0,10 ));
        currentDataPoint.valueSoilHum=(4095 - currentDataPoint.valueSoilHum)/41;
			  currentDataPoint.valuelight = (Get_Adc_Average(ADC_CHANNEL_1,10 ))/41;

        //显示三种数据
        OLED_ShowNum(40,2,(uint16_t)currentDataPoint.valueAirTemp,2,16);
        OLED_ShowNum(40,4,(uint16_t)currentDataPoint.valueAirHum,2,16);
        OLED_ShowNum(40,6,(uint16_t)(currentDataPoint.valueSoilHum),2,16);
        OLED_ShowNum(90,6,(uint16_t)(currentDataPoint.valuelight),3,16);
			
			
        if(currentDataPoint.valueMODEL==0) //自动模式
        {
            if(currentDataPoint.valueAirTemp > currentDataPoint.valueTempSet
                    || currentDataPoint.valueAirHum < currentDataPoint.valueHumiSet)
            {
                HUMON;
                currentDataPoint.valueaddhumiopen  = 1;
            }
            else
            {
                HUMOFF;
                currentDataPoint.valueaddhumiopen = 0;
            }
            if(currentDataPoint.valueSoilHum <  currentDataPoint.valueSoilSet)
            {
                LEDON;
                currentDataPoint.valueBoomOpen = 1;
            }
            else
            {
                LEDOFF;
                currentDataPoint.valueBoomOpen =0;
            }
						if(currentDataPoint.valuelight < currentDataPoint.valuelightset)
						{
						  LED1ON;currentDataPoint.valueLED = 1;
						}
						else
						{
						  LED1OFF;currentDataPoint.valueLED = 0;
						}
//            if(currentDataPoint.valueAirTemp > currentDataPoint.valueTempSet
//                    || currentDataPoint.valueAirHum < currentDataPoint.valueHumiSet
//                    ||currentDataPoint.valueSoilHum <  currentDataPoint.valueSoilSet)
//            {
//                BEEpON;LED1ON;
//            }
//            else
//            {
//                BEEpOFF;LED1FF;
//            }
						
						 if(currentDataPoint.valueAirTemp > currentDataPoint.valueTempSet )
            {
               OLED_ShowString(80,2,"*",16);	// currentDataPoint.valueTempAlarm = 1;
            }
            else
            {
                OLED_ShowString(80,2," ",16);	// currentDataPoint.valueTempAlarm = 0;
            }
						
				   if(currentDataPoint.valueAirHum < currentDataPoint.valueHumiSet )
            {
               OLED_ShowString(80,4,"*",16);	// currentDataPoint.valueTempAlarm = 1;
            }
            else
            {
                OLED_ShowString(80,4," ",16);	// currentDataPoint.valueTempAlarm = 0;
            }
						
					 if(currentDataPoint.valueSoilHum <  currentDataPoint.valueSoilSet )
            {
               OLED_ShowString(80,6,"*",16);	// currentDataPoint.valueTempAlarm = 1;
            }
            else
            {
                OLED_ShowString(80,6," ",16);	// currentDataPoint.valueTempAlarm = 0;
            }
        }
        thLastTimer = gizGetTimerCount();
    }
}


/**
* Data point initialization function

* In the function to complete the initial user-related data
* @param none
* @return none
* @note The developer can add a data point state initialization value within this function
*/
void userInit(void)
{
    memset((uint8_t*)&currentDataPoint, 0, sizeof(dataPoint_t));

    /** Warning !!! DataPoint Variables Init , Must Within The Data Range **/

   currentDataPoint.valueBoomOpen = 0;
    currentDataPoint.valueaddhumiopen = 0;
    currentDataPoint.valueMODEL =0 ;
    currentDataPoint.valueSoilSet = 0;
    currentDataPoint.valueHumiSet = 50;
    currentDataPoint.valueTempSet = 30;
    currentDataPoint.valueAirTemp =0 ;
    currentDataPoint.valueAirHum = 0;
    currentDataPoint.valueSoilHum =0 ;
    currentDataPoint.valueTempAlarm = 0;
    currentDataPoint.valueHumiAlarm = 0;
    currentDataPoint.valueLightAlarm = 0;
    currentDataPoint.valueSoilHumiAlarm = 0;
    currentDataPoint.valueLED = 0;
currentDataPoint.valuelightset = 30;

}


/**
* @brief Millisecond timing maintenance function, milliseconds increment, overflow to zero

* @param none
* @return none
*/
void gizTimerMs(void)
{
    timerMsCount++;
}

/**
* @brief Read millisecond count

* @param none
* @return millisecond count
*/
uint32_t gizGetTimerCount(void)
{
    return timerMsCount;
}

/**
* @brief MCU reset function

* @param none
* @return none
*/
void mcuRestart(void)
{
    __set_FAULTMASK(1);
    HAL_NVIC_SystemReset();
}

/**@} */

#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
   set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
/**
  * @brief  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
PUTCHAR_PROTOTYPE
{
    /* Place your implementation of fputc here */
    /* e.g. write a character to the USART1 and Loop until the end of transmission */
    HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);

    return ch;
}

/**
  * @brief  Period elapsed callback in non blocking mode
  * @param  htim : TIM handle
  * @retval None
  */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim==&htim2)
    {
        keyHandle((keysTypedef_t *)&keys);
        gizTimerMs();
    }
}

/**
* @brief Timer TIM3 init function

* @param none
* @return none
*/
void timerInit(void)
{
    HAL_TIM_Base_Start_IT(&htim2);
}

/**
  * @brief  This function handles USART IDLE interrupt.
  */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef*UartHandle)
{
    if(UartHandle->Instance == USART2)
    {
        gizPutData((uint8_t *)&aRxBuffer, 1);

        HAL_UART_Receive_IT(&huart2, (uint8_t *)&aRxBuffer, 1);//开启下一次接收中断
    }
}

/**
* @brief USART init function

* Serial communication between WiFi modules and device MCU
* @param none
* @return none
*/
void uartInit(void)
{
    HAL_UART_Receive_IT(&huart2, (uint8_t *)&aRxBuffer, 1);//开启下一次接收中断
}

/**
* @brief Serial port write operation, send data to WiFi module
*
* @param buf      : buf address
* @param len      : buf length
*
* @return : Return effective data length;-1，return failure
*/
int32_t uartWrite(uint8_t *buf, uint32_t len)
{
    uint8_t crc[1] = {0x55};
    uint32_t i = 0;

    if(NULL == buf)
    {
        return -1;
    }

    for(i=0; i<len; i++)
    {
        HAL_UART_Transmit_IT(&huart2, (uint8_t *)&buf[i], 1);
        while (huart2.gState != HAL_UART_STATE_READY);//Loop until the end of transmission

        if(i >=2 && buf[i] == 0xFF)
        {
            HAL_UART_Transmit_IT(&huart2, (uint8_t *)&crc, 1);
            while (huart2.gState != HAL_UART_STATE_READY);//Loop until the end of transmission
        }
    }

#ifdef PROTOCOL_DEBUG
    GIZWITS_LOG("MCU2WiFi[%4d:%4d]: ", gizGetTimerCount(), len);
    for(i=0; i<len; i++)
    {
        GIZWITS_LOG("%02x ", buf[i]);

        if(i >=2 && buf[i] == 0xFF)
        {
            GIZWITS_LOG("%02x ", 0x55);
        }
    }
    GIZWITS_LOG("\n");
#endif

    return len;
}
